home *** CD-ROM | disk | FTP | other *** search
- Path: tank.news.pipex.net!pipex!demon!le-vamp.demon.co.uk
- From: Kurt@le-vamp.demon.co.uk (Kurt Frary)
- Newsgroups: comp.lang.c++
- Subject: help borland c++ and tasm ?
- Date: Tue, 09 Jan 1996 13:31:16 GMT
- Message-ID: <821194253.362@le-vamp.demon.co.uk>
- Reply-To: kurt@le-vamp.demon.co.uk
- NNTP-Posting-Host: le-vamp.demon.co.uk
- X-NNTP-Posting-Host: le-vamp.demon.co.uk
- X-Newsreader: Forte Agent .99c/32.126
-
- If anyone can help it would be much appreciated!
-
-
-
-
- these are the errors I get:-
-
- Linking cpuid.exe:
- Linker Warning: DOSSEG directive ignored in module
- X:\KURT'S~1\KURT'S~1\CPUIDP~1\cpuid3a.asm
- Linker Error: Undefined symbol _printf in module CPUID3B.C
- Linker Error: Undefined symbol _features_edx in module CPUID3B.C
- Linker Error: Undefined symbol _cpu_signature in module CPUID3B.C
- Linker Error: Undefined symbol F_LXRSH@ in module CPUID3B.C
- Linker Error: Undefined symbol _cpu_type in module CPUID3B.C
- Linker Error: Undefined symbol _intel_CPU in module CPUID3B.C
- Linker Error: Undefined symbol _fpu_type in module CPUID3B.C
- Linker Error: Undefined symbol _cpuid_flag in module CPUID3B.C
- Linker Error: Undefined symbol _get_fpu_type in module CPUID3B.C
- Linker Error: Undefined symbol _get_cpu_type in module CPUID3B.C
-
-
-
- Here's the C source code as you can see it is from intel, I create a
- project and add these two file and it will not compile, these are the
- only two files in the project!
-
- /* Filename: cpuid3b.c */
- /* Copyright 1994 by Intel Corp. */
- /* */
- /* This program has been developed by Intel Corporation. */
- /* */
- /* Intel specifically disclaims all warranties, express or */
- /* implied, and all liability, including consequential and other */
- /* indirect damages, for the use of this code, including */
- /* liability for infringement of any proprietary rights, and */
- /* including the warranties of merchantability and fitness for a */
- /* particular purpose. Intel does not assume any responsibility */
- /* for any errors which may appear in this code nor any */
- /* responsibility to update it. */
- /* */
- /* This program contains three parts: */
- /* Part 1: Identifies CPU type in the variable _cpu_type: */
- /* */
- /* Part 2: Identifies FPU type in the variable _fpu_type: */
- /* */
- /* Part 3: Prints out the appropriate message. */
- /* */
- /* This program has been tested with the Microsoft C compiler. */
- /* If this code is compiled with no options specified and linked */
- /* with the cpuid3a module, it correctly identifies the current */
- /* Intel 8086/8088, 80286, 80386, 80486, and Pentium(tm) */
- /* processors in the real-address mode. */
-
- #define FPU_FLAG 0x0001
- #define VME_FLAG 0x0002
- #define PSE_FLAG 0x0008
- #define MCE_FLAG 0x0080
- #define CMPXCHG8B_FLAG 0x0100
- #define APIC_FLAG 0x0200
-
- extern char cpu_type;
- extern char fpu_type;
- extern char cpuid_flag;
- extern char intel_CPU;
- extern char vendor_id[12];
- extern long cpu_signature;
- extern long features_ecx;
- extern long features_edx;
- extern long features_ebx;
-
- main() {
- get_cpu_type();
- get_fpu_type();
- print();
- }
-
- print() {
- printf("This system has a");
- if (cpuid_flag == 0) {
- switch (cpu_type) {
- case 0:
- printf("n 8086/8088 processor");
- if (fpu_type) printf(" and an 8087 math coprocessor");
- break;
- case 2:
- printf("n 80286 processor");
- if (fpu_type) printf(" and an 80287 math coprocessor");
- break;
- case 3:
- printf("n 80386 processor");
- if (fpu_type == 2)
- printf(" and an 80287 math coprocessor");
- else if (fpu_type)
- printf(" and an 80387 math coprocessor");
- break;
- case 4:
- if (fpu_type) printf("n 80486DX, 80486DX2 processor or \
- 80487SX math coprocessor");
- else printf("n 80486SX processor");
- break;
- default:
- printf("n unknown processor");
- }
- } else {
- /* using cpuid instruction */
- if (intel_CPU) {
- if (cpu_type == 4) {
- switch ((cpu_signature>>4)&0xf) {
- case 0:
- case 1:
- printf(" Genuine Intel486(TM) DX processor");
- break;
- case 2:
- printf(" Genuine Intel486(TM) SX processor");
- break;
- case 3:
- printf(" Genuine IntelDX2(TM) processor");
- break;
- case 4:
- printf(" Genuine Intel486(TM) processor");
- break;
- case 5:
- printf(" Genuine IntelSX2(TM) processor");
- break;
- case 7:
- printf(" Genuine Write-Back Enhanced \
- IntelDX2(TM) processor");
- break;
- case 8:
- printf(" Genuine IntelDX4(TM) processor");
- break;
- default:
- printf(" Genuine Intel486(TM) processor");
- }
- } else if (cpu_type == 5)
- printf(" Genuine Intel Pentium(TM) processor");
- else
- printf("n unknown Genuine Intel processor");
- printf("\nProcessor Family: %X", cpu_type);
- printf("\nModel: %X", (cpu_signature>>4)&0xf);
- printf("\nStepping: %X\n", cpu_signature&0xf);
- if (cpu_signature & 0x1000)
- printf("\nThe processor is an OverDrive(TM) upgrade \
- processor");
- else if (cpu_signature & 0x2000)
- printf("\nThe processor is the upgrade processor \
- in a dual processor system");
- if (features_edx & FPU_FLAG)
- printf("\nThe processor contains an on-chip FPU");
- if (features_edx & MCE_FLAG)
- printf("\nThe processor supports Machine Check \
- Exceptions");
- if (features_edx & CMPXCHG8B_FLAG)
- printf("\nThe processor supports the CMPXCHG8B \
- instruction");
- if (features_edx & VME_FLAG)
- printf("\nThe processor supports Virtual Mode \
- Extensions");
- if (features_edx & PSE_FLAG)
- printf("\nThe processor supports Page Size \
- Extensions");
- if (features_edx & APIC_FLAG)
- printf("\nThe processor contains an on-chip APIC");
- } else {
- printf("t least an 80486 processor.\nIt does not \
- contain a Genuine Intel part and as a result, the\nCPUID detection \
- information cannot be determined at this time.");
- }
- }
- printf("\n");
- }
-
-
-
-
- Here's the assembler!
-
- ; Filename: cpuid3a.asm
- ; Copyright 1993, 1994 by Intel Corp.
- ;
- ; This program has been developed by Intel Corporation.
- ; Intel has intellectual property
- ; rights which it may assert if another manufacturer's processor
- ; mis-identifies itself as being "GenuineIntel" when the CPUID
- ; instruction is executed.
- ;
- ; Intel specifically disclaims all warranties, express or
- ; implied, and all liability, including consequential and other
- ; indirect damages, for the use of this code, including
- ; liability for infringement of any proprietary rights, and
- ; including the warranties of merchantability and fitness for a
- ; particular purpose. Intel does not assume any responsibility
- ; for any errors which may appear in this code nor any
- ; responsibility to update it.
- ;
- ; This code contains two procedures:
- ; _get_cpu_type: Identifies processor type in _cpu_type:
- ; 0=8086/8088 processor
- ; 2=Intel 286 processor
- ; 3=Intel386(TM) family processor
- ; 4=Intel486(TM) family processor
- ; 5=Pentium(TM) family processor
- ;
- ; _get_fpu_type: Identifies FPU type in _fpu_type:
- ; 0=FPU not present
- ; 1=FPU present
- ; 2=287 present (only if _cpu_type=3)
- ; 3=387 present (only if _cpu_type=3)
- ;
- ; This program has been tested with the MASM assembler.
- ; This code correctly detects the current Intel 8086/8088,
- ; 80286, 80386, 80486, and Pentium(tm) processors in the
- ; real-address mode.
- ;
- ; To assemble this code with TASM, add the JUMPS directive.
- jumps ; Uncomment this line for TASM
-
-
- TITLE cpuid3
- DOSSEG
- .model small
-
- CPU_ID MACRO
- db 0fh ; Hardcoded CPUID instruction
- db 0a2h
- ENDM
-
- .data
- public _cpu_type
- public _fpu_type
- public _cpuid_flag
- public _intel_CPU
- public _vendor_id
- public _cpu_signature
- public _features_ecx
- public _features_edx
- public _features_ebx
- _cpu_type db 0
- _fpu_type db 0
- _cpuid_flag db 0
- _intel_CPU db 0
- _vendor_id db "------------"
- intel_id db "GenuineIntel"
- _cpu_signature dd 0
- _features_ecx dd 0
- _features_edx dd 0
- _features_ebx dd 0
- fp_status dw 0
-
- .code
- .8086
-
- ;*********************************************************************
-
- public _get_cpu_type
- _get_cpu_type proc
-
- ; This procedure determines the type of processor in a system
- ; and sets the _cpu_type variable with the appropriate
- ; value. If the CPUID instruction is available, it is used
- ; to determine more specific details about the processor.
- ; All registers are used by this procedure, none are preserved.
- ; To avoid AC faults, the AM bit in CR0 must not be set.
-
- ; Intel 8086 processor check
- ; Bits 12-15 of the FLAGS register are always set on the
- ; 8086 processor.
-
- check_8086:
- pushf ; push original FLAGS
- pop ax ; get original FLAGS
- mov cx, ax ; save original FLAGS
- and ax, 0fffh ; clear bits 12-15 in FLAGS
- push ax ; save new FLAGS value on stack
- popf ; replace current FLAGS value
- pushf ; get new FLAGS
- pop ax ; store new FLAGS in AX
- and ax, 0f000h ; if bits 12-15 are set, then
- cmp ax, 0f000h ; processor is an 8086/8088
- mov _cpu_type, 0 ; turn on 8086/8088 flag
- je end_cpu_type ; jump if processor is 8086/8088
-
- ; Intel 286 processor check
- ; Bits 12-15 of the FLAGS register are always clear on the
- ; Intel 286 processor in real-address mode.
-
- .286
- check_80286:
- or cx, 0f000h ; try to set bits 12-15
- push cx ; save new FLAGS value on stack
- popf ; replace current FLAGS value
- pushf ; get new FLAGS
- pop ax ; store new FLAGS in AX
- and ax, 0f000h ; if bits 12-15 are clear
- mov _cpu_type, 2 ; processor=80286, turn on 80286 flag
- jz end_cpu_type ; if no bits set, processor is 80286
-
- ; Intel386 processor check
- ; The AC bit, bit #18, is a new bit introduced in the EFLAGS
- ; register on the Intel486 processor to generate alignment
- ; faults.
- ; This bit cannot be set on the Intel386 processor.
-
- .386 ; it is safe to use 386 instructions
- check_80386:
- pushfd ; push original EFLAGS
- pop eax ; get original EFLAGS
- mov ecx, eax ; save original EFLAGS
- xor eax, 40000h ; flip AC bit in EFLAGS
- push eax ; save new EFLAGS value on stack
- popfd ; replace current EFLAGS value
- pushfd ; get new EFLAGS
- pop eax ; store new EFLAGS in EAX
- xor eax, ecx ; can't toggle AC bit, processor=80386
- mov _cpu_type, 3 ; turn on 80386 processor flag
- jz end_cpu_type ; jump if 80386 processor
-
- push ecx
- popfd ; restore AC bit in EFLAGS first
-
- ; Intel486 processor check
- ; Checking for ability to set/clear ID flag (Bit 21) in EFLAGS
- ; which indicates the presence of a processor with the CPUID
- ; instruction.
-
- .486
- check_80486:
- mov _cpu_type, 4 ; turn on 80486 processor flag
- mov eax, ecx ; get original EFLAGS
- xor eax, 200000h ; flip ID bit in EFLAGS
- push eax ; save new EFLAGS value on stack
- popfd ; replace current EFLAGS value
- pushfd ; get new EFLAGS
- pop eax ; store new EFLAGS in EAX
- xor eax, ecx ; can't toggle ID bit,
- je end_cpu_type ; processor=80486
-
- ; Execute CPUID instruction to determine vendor, family,
- ; model, stepping and features. For the purpose of this
- ; code, only the initial set of CPUID information is saved.
-
- mov _cpuid_flag, 1 ; flag indicating use of CPUID inst.
- push ebx ; save registers
- push esi
- push edi
- mov eax, 0 ; set up for CPUID instruction
- CPU_ID ; get and save vendor ID
-
- mov dword ptr _vendor_id, ebx
- mov dword ptr _vendor_id[+4], edx
- mov dword ptr _vendor_id[+8], ecx
-
- mov si, ds
- mov es, si
-
- mov si, offset _vendor_id
- mov di, offset intel_id
- mov cx, 12 ; should be length intel_id
- cld ; set direction flag
- repe cmpsb ; compare vendor ID to "GenuineIntel"
- jne end_cpuid_type ; if not equal, not an Intel processor
-
- mov _intel_CPU, 1 ; indicate an Intel processor
- cmp eax, 1 ; make sure 1 is valid input for CPUID
- jl end_cpuid_type ; if not, jump to end
- mov eax, 1
- CPU_ID ; get family/model/stepping/features
- mov _cpu_signature, eax
- mov _features_ebx, ebx
- mov _features_edx, edx
- mov _features_ecx, ecx
-
- shr eax, 8 ; isolate family
- and eax, 0fh
- mov _cpu_type, al ; set _cpu_type with family
-
- end_cpuid_type:
- pop edi ; restore registers
- pop esi
- pop ebx
-
- .8086
- end_cpu_type:
- ret
- _get_cpu_type endp
-
- ;*********************************************************************
-
- public _get_fpu_type
- _get_fpu_type proc
-
- ; This procedure determines the type of FPU in a system
- ; and sets the _fpu_type variable with the appropriate value.
- ; All registers are used by this procedure, none are preserved.
-
- ; Coprocessor check
- ; The algorithm is to determine whether the floating-point
- ; status and control words are present. If not, no
- ; coprocessor exists. If the status and control words can
- ; be saved, the correct coprocessor is then determined
- ; depending on the processor type. The Intel386 processor can
- ; work with either an Intel287 NDP or an Intel387 NDP.
- ; The infinity of the coprocessor must be checked to determine
- ; the correct coprocessor type.
-
- fninit ; reset FP status word
- mov fp_status, 5a5ah; initialize temp word to non-zero
- fnstsw fp_status ; save FP status word
- mov ax, fp_status ; check FP status word
- cmp al, 0 ; was correct status written
- mov _fpu_type, 0 ; no FPU present
- jne end_fpu_type
-
- check_control_word:
- fnstcw fp_status ; save FP control word
- mov ax, fp_status ; check FP control word
- and ax, 103fh ; selected parts to examine
- cmp ax, 3fh ; was control word correct
- mov _fpu_type, 0
- jne end_fpu_type ; incorrect control word, no FPU
- mov _fpu_type, 1
-
- ; 80287/80387 check for the Intel386 processor
-
- check_infinity:
- cmp _cpu_type, 3
- jne end_fpu_type
- fld1 ; must use default control from FNINIT
- fldz ; form infinity
- fdiv ; 8087/Intel287 NDP say +inf = -inf
- fld st ; form negative infinity
- fchs ; Intel387 NDP says +inf <> -inf
- fcompp ; see if they are the same
- fstsw fp_status ; look at status from FCOMPP
- mov ax, fp_status
- mov _fpu_type, 2 ; store Intel287 NDP for FPU type
- sahf ; see if infinities matched
- jz end_fpu_type ; jump if 8087 or Intel287 is present
- mov _fpu_type, 3 ; store Intel387 NDP for FPU type
- end_fpu_type:
- ret
- _get_fpu_type endp
-
- end
-
-
-
-
- MM MM A SS K K EEE RR
- M M M A A S K K E R R
- M M AAA S KK EEE RR
- M M A A S K K E R R
- M M A A SS K K EEE R R :)
-
-